package org.jeecg.modules.mes.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.mes.entity.MesProductionPlanTask;
import org.jeecg.modules.mes.entity.MesTaskParticipant;
import org.jeecg.modules.mes.mapper.MesTaskParticipantMapper;
import org.jeecg.modules.mes.service.IMesProductionPlanTaskService;
import org.jeecg.modules.mes.service.IMesTaskParticipantService;
import org.jeecg.modules.system.entity.SysEmployee;
import org.jeecg.modules.system.service.ISysEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Description: 任务参与者服务实现
 * @Author: jeecg-boot
 * @Date: 2025-08-30
 * @Version: V2.0
 */
@Service
@Slf4j
public class MesTaskParticipantServiceImpl extends ServiceImpl<MesTaskParticipantMapper, MesTaskParticipant> implements IMesTaskParticipantService {

    @Autowired
    private MesTaskParticipantMapper taskParticipantMapper;

    @Autowired
    private IMesProductionPlanTaskService taskService;

    @Autowired
    private ISysEmployeeService employeeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean claimTask(String taskId, String employeeId, Integer claimQuantity, BigDecimal participationRatio) {
        try {
            // 1. 获取任务信息
            MesProductionPlanTask task = taskService.getById(taskId);
            if (task == null) {
                throw new JeecgBootException("任务不存在");
            }

            // 2. 检查任务状态
            if (task.getStatus() != 0) {
                throw new JeecgBootException("任务状态不允许领取");
            }

            // 3. 检查员工是否已参与该任务
            MesTaskParticipant existingParticipant = checkEmployeeParticipation(taskId, employeeId);
            if (existingParticipant != null) {
                throw new JeecgBootException("员工已参与该任务");
            }

            // 4. 检查协作限制
            if (task.getCollaborationType() == 0 && task.getCurrentParticipants() > 0) {
                throw new JeecgBootException("单人任务不允许多人参与");
            }

            if (task.getCollaborationType() == 1 && task.getCurrentParticipants() >= task.getMaxParticipants()) {
                throw new JeecgBootException("参与人数已达上限");
            }

            // 5. 获取员工信息
            SysEmployee employee = employeeService.getById(employeeId);
            if (employee == null) {
                throw new JeecgBootException("员工不存在");
            }

            // 6. 创建参与者记录
            MesTaskParticipant participant = new MesTaskParticipant();
            participant.setTaskId(taskId);
            participant.setEmployeeId(employeeId);
            participant.setEmployeeName(employee.getEmpName());
            participant.setEmployeeNo(employee.getEmpNo());
            participant.setParticipationRatio(participationRatio != null ? participationRatio : BigDecimal.valueOf(100));
            participant.setClaimedQuantity(claimQuantity != null ? claimQuantity : task.getTaskQuantity());
            participant.setCompletedQuantity(0);
            participant.setClaimedTime(new Date());
            participant.setActualHours(BigDecimal.ZERO);
            participant.setStatus(0); // 已领取
            participant.setCreateTime(new Date());

            boolean result = this.save(participant);

            // 7. 更新任务参与人数
            if (result) {
                LambdaUpdateWrapper<MesProductionPlanTask> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(MesProductionPlanTask::getId, taskId)
                           .setSql("current_participants = current_participants + 1");
                taskService.update(updateWrapper);
            }

            log.info("员工领取任务成功: taskId={}, employeeId={}, claimQuantity={}", taskId, employeeId, claimQuantity);
            return result;
        } catch (Exception e) {
            log.error("员工领取任务失败: taskId={}, employeeId={}", taskId, employeeId, e);
            throw new JeecgBootException("员工领取任务失败: " + e.getMessage());
        }
    }

    @Override
    public List<MesTaskParticipant> getTaskParticipants(String taskId) {
        try {
            return taskParticipantMapper.getParticipantsByTaskId(taskId);
        } catch (Exception e) {
            log.error("获取任务参与者失败: taskId={}", taskId, e);
            throw new JeecgBootException("获取任务参与者失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateParticipantProgress(String participantId, Integer completedQuantity) {
        try {
            int result = taskParticipantMapper.updateParticipantProgress(participantId, completedQuantity);
            
            if (result > 0) {
                log.info("更新参与者进度成功: participantId={}, completedQuantity={}", 
                        participantId, completedQuantity);
            }
            
            return result > 0;
        } catch (Exception e) {
            log.error("更新参与者进度失败: participantId={}, completedQuantity={}", 
                    participantId, completedQuantity, e);
            throw new JeecgBootException("更新参与者进度失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeParticipation(String participantId, BigDecimal qualityScore, BigDecimal efficiencyScore) {
        try {
            int result = taskParticipantMapper.completeParticipation(participantId, qualityScore, efficiencyScore);
            
            if (result > 0) {
                log.info("完成任务参与成功: participantId={}, qualityScore={}, efficiencyScore={}", 
                    participantId, qualityScore, efficiencyScore);
            }
            
            return result > 0;
        } catch (Exception e) {
            log.error("完成任务参与失败: participantId={}, qualityScore={}, efficiencyScore={}", 
                participantId, qualityScore, efficiencyScore, e);
            throw new JeecgBootException("完成任务参与失败: " + e.getMessage());
        }
    }

    @Override
    public List<MesTaskParticipant> getEmployeeParticipations(String employeeId, Integer status) {
        try {
            return taskParticipantMapper.getParticipationsByEmployeeId(employeeId, status);
        } catch (Exception e) {
            log.error("获取员工参与任务失败: employeeId={}, status={}", employeeId, status, e);
            throw new JeecgBootException("获取员工参与任务失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startTaskExecution(String participantId) {
        try {
            LambdaUpdateWrapper<MesTaskParticipant> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MesTaskParticipant::getId, participantId)
                        .set(MesTaskParticipant::getStatus, 1) // 进行中
                        .set(MesTaskParticipant::getStartTime, new Date())
                        .set(MesTaskParticipant::getUpdateTime, new Date());
            
            return this.update(updateWrapper);
        } catch (Exception e) {
            log.error("开始任务执行失败: participantId={}", participantId, e);
            throw new JeecgBootException("开始任务执行失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pauseTaskExecution(String participantId, String reason) {
        try {
            LambdaUpdateWrapper<MesTaskParticipant> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MesTaskParticipant::getId, participantId)
                        .set(MesTaskParticipant::getStatus, 3) // 已暂停
                        .set(MesTaskParticipant::getRemark, reason)
                        .set(MesTaskParticipant::getUpdateTime, new Date());
            
            return this.update(updateWrapper);
        } catch (Exception e) {
            log.error("暂停任务执行失败: participantId={}, reason={}", participantId, reason, e);
            throw new JeecgBootException("暂停任务执行失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resumeTaskExecution(String participantId) {
        try {
            LambdaUpdateWrapper<MesTaskParticipant> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MesTaskParticipant::getId, participantId)
                        .set(MesTaskParticipant::getStatus, 1) // 进行中
                        .set(MesTaskParticipant::getUpdateTime, new Date());
            
            return this.update(updateWrapper);
        } catch (Exception e) {
            log.error("恢复任务执行失败: participantId={}", participantId, e);
            throw new JeecgBootException("恢复任务执行失败: " + e.getMessage());
        }
    }

    @Override
    public MesTaskParticipant getTaskParticipantStats(String taskId) {
        try {
            return taskParticipantMapper.getTaskParticipantStats(taskId);
        } catch (Exception e) {
            log.error("获取任务参与者统计失败: taskId={}", taskId, e);
            throw new JeecgBootException("获取任务参与者统计失败");
        }
    }

    @Override
    public MesTaskParticipant checkEmployeeParticipation(String taskId, String employeeId) {
        try {
            return taskParticipantMapper.checkEmployeeParticipation(taskId, employeeId);
        } catch (Exception e) {
            log.error("检查员工参与状态失败: taskId={}, employeeId={}", taskId, employeeId, e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeParticipant(String participantId) {
        try {
            // 获取参与者信息
            MesTaskParticipant participant = this.getById(participantId);
            if (participant == null) {
                throw new JeecgBootException("参与者不存在");
            }

            // 检查是否可以移除
            if (participant.getStatus() == 2) {
                throw new JeecgBootException("已完成的参与者不能移除");
            }

            boolean result = this.removeById(participantId);

            // 更新任务参与人数
            if (result) {
                LambdaUpdateWrapper<MesProductionPlanTask> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(MesProductionPlanTask::getId, participant.getTaskId())
                           .setSql("current_participants = current_participants - 1");
                taskService.update(updateWrapper);
            }

            return result;
        } catch (Exception e) {
            log.error("移除任务参与者失败: participantId={}", participantId, e);
            throw new JeecgBootException("移除任务参与者失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchAssignTask(String taskId, List<String> employeeIds, List<Integer> quantities, List<BigDecimal> ratios) {
        try {
            if (employeeIds.size() != quantities.size() || employeeIds.size() != ratios.size()) {
                throw new JeecgBootException("参数数量不匹配");
            }

            for (int i = 0; i < employeeIds.size(); i++) {
                claimTask(taskId, employeeIds.get(i), quantities.get(i), ratios.get(i));
            }

            return true;
        } catch (Exception e) {
            log.error("批量分配任务失败: taskId={}, employeeIds={}", taskId, employeeIds, e);
            throw new JeecgBootException("批量分配任务失败: " + e.getMessage());
        }
    }

    @Override
    public void removeEmployeeParticipation(String taskId, String employeeId) {
        remove(new LambdaQueryWrapper<MesTaskParticipant>()
                .eq(MesTaskParticipant::getTaskId, taskId)
                .eq(MesTaskParticipant::getEmployeeId, employeeId));
    }
}
